<?php
/**
 * Created by PhpStorm.
 * User: LiuJiaJun
 * Date: 2018/12/5
 * Time: 14:06
 */

namespace api\storage\controller;


use api\storage\common\Constant;
use api\storage\common\OutputFactory;
use api\storage\model\SupplierModel;
use api\storage\service\BomService;
use service\logger\LoggerFactory;
use think\Request;

class OutputController extends AppBaseController
{

    public function __construct(Request $request = null)
    {
        parent::__construct($request);
    }

    /**
     * @api {GET} /api/storage/output 1.获取出库数据
     * @apiHeader {string} XX-Device-Type 说明登录的设备 mobile \ android \ iphone \ ipad \ web \ pc \ mac \ wxapp
     * @apiHeader {string} XX-Token token信息，登录后返回
     * @apiHeader {string} XX-Api-Version api的版本信息
     * @apiName  index
     * @apiGroup  output
     * @apiVersion 0.0.1
     * @apiDescription 根据出库单查找出出库数据
     *
     * @apiParam {string} bomId 出库单
     * @apiParam {int} isComposite 是否边入库边装车
     *
     * @apiSuccess {string} code 0 | 224 当 code=224 的时候表示不需要发实物，直接结束出库
     * @apiSuccess {string} msg 请求成功
     * @apiSuccess {Array} data
     * @apiSuccess {Array} data.performList 盘料
     * @apiSuccess {Array} data.batchList 容器
     * @apiSuccess {Array} data.lackInfoList 缺料信息
     * @apiSuccess {Array} data.planFeedList 计划投料数
     * @apiSuccess {Array} data.returnMaterial 物料归还信息
     * @apiSuccess {Array} data.carData 如果边出库边装车，则会有这个字段
     * @apiSuccess {string} data.carData.aCount a类型所需数量
     * @apiSuccess {string} data.carData.bCount b类型所需数量
     * @apiError  Error
     **/
    public function index()
    {
        $bomId = input('bomId');
        $isComposite = input('isComposite');
        if (empty($bomId)) {
            $this->error('bomId不能为空');
        }
        $bomInfo = BomService::getBomInfo($bomId);
        //不存在出库信息
        if (empty($bomInfo)) {
            $this->error('该订单不存在');
        }
        //出库已经完成
        if ($bomInfo->getData('status') == 1) {
            $this->error('该订单已经完成');
        }
        $supplierModel = new SupplierModel();
        $supplier = $supplierModel->findByUuid($bomInfo->getData('supplier_uuid'));
        if (empty($supplier)) {
            $this->error('出库单的厂商不在库中');
        }
        //奇怪的情况，如果下面两行代码在OutputFactory下面的话，service里面的注释没有写到文件日志文件里
        $logger = LoggerFactory::getLogger('output');
        $logger->debug("账号：{$this->getUsername()}，请求出库单：{$bomId}的出库数据");
        $service = OutputFactory::getBomService($this->getType($bomId));
        $result = $service->getBomData($bomId, $bomInfo, $supplier->getData('supplier_id'), $this->getStorageUuid(), $isComposite);
        switch ($result['status']) {
            case -3:
                //这种情况满足厂商库存充足
                $this->error('退料单没有数据');
                break;
            case -2:
                $this->error('该订单不是正在出库的订单');
                break;
            case -1:
                $this->error('订单没有物料信息');
                break;
            case 0:
                $this->error('获取失败');
                break;
            case 1:
                $this->success('获取成功', $result['data']);
                break;
            case 2:
                //这种情况满足厂商库存充足
                $this->success('获取成功', $result['data']);
                break;
            case 3:
                //这种情况满足厂商库存充足
                $this->success('获取成功', $result['data'], Constant::RETURN_CODE_OUTPUT_NOT_NEED_REELS);
                break;
            default:
                $this->error('请求失败');
        }
    }

    /**
     * @api {POST} /api/storage/output/output_confirm 2.1确认出库
     * @apiHeader {string} XX-Device-Type 说明登录的设备 mobile \ android \ iphone \ ipad \ web \ pc \ mac \ wxapp
     * @apiHeader {string} XX-Token token信息，登录后返回
     * @apiHeader {string} XX-Api-Version api的版本信息
     * @apiName  confirmOutput
     * @apiGroup  output
     * @apiVersion 0.0.1
     * @apiDescription 确认出库，如果是第一个人确认的话，那么就将灯亮起来
     *
     * @apiParam {string} bomId 出库单
     * @apiParam {array} carIds 如果是变出库边装车，需要该参数
     *
     * @apiSuccess {string} code 0
     * @apiSuccess {string} msg 确认成功
     * @apiSuccess {Array} data
     * @apiSuccess {Array} data.performList 盘料
     * @apiSuccess {Array} data.batchList 容器
     * @apiSuccess {Array} data.lackInfoList 缺料信息
     * @apiSuccess {Array} data.planFeedList 计划投料数
     * @apiSuccess {Array} data.returnMaterial 物料归还信息
     * @apiError  Error
     **/
    public function confirmOutput()
    {
        $bomId = input('bomId');
        if (isset($_POST['carIds'])) {
            $carIds = $this->jsonDecode($_POST['carIds']);
        } else {
            $carIds = [];
        }
        $service = OutputFactory::getBomService($this->getType($bomId));
        $result = $service->confirm($bomId, $this->getStorageUuid(), $this->getNickname(), $carIds);
        switch ($result['status']) {
            case 0:
                $this->error('不是同一个出库单');
                break;
            case 1:
                $this->success('确认成功', $result['data']);
                break;
            case 3:
                $this->success('没有出库的物料', $result['data']);
                break;
            default:
                $this->error('请求失败');
        }
    }

    /**
     * @api {DELETE} /api/storage/output/output_cancel 2.2取消出库
     * @apiHeader {string} XX-Device-Type 说明登录的设备 mobile \ android \ iphone \ ipad \ web \ pc \ mac \ wxapp
     * @apiHeader {string} XX-Token token信息，登录后返回
     * @apiHeader {string} XX-Api-Version api的版本信息
     * @apiName  cancelOutput
     * @apiGroup  output
     * @apiVersion 0.0.1
     * @apiDescription 取消出库，将仓库字段清除，文件删除
     *
     * @apiParam {string} bomId 出库单
     *
     * @apiSuccess {string} code 0
     * @apiSuccess {string} msg 取消成功
     * @apiError  Error
     **/
    public function cancelOutput()
    {
        $bomId = input('bomId');
        $service = OutputFactory::getBomService($this->getType($bomId));
        $result = $service->cancel($bomId, $this->getStorageUuid(), $this->getNickname());
        switch ($result['status']) {
            case -1:
                $this->error('出库单已经确认，不能取消');
                break;
            case 0:
                $this->error('不是同一个出库单');
                break;
            case 1:
                $this->success('取消成功');
                break;
            default:
                $this->error('请求失败');
        }
    }

    /**
     * @api {GET} /api/storage/output/status_check 3~5检查出库单状态
     * @apiHeader {string} XX-Device-Type 说明登录的设备 mobile \ android \ iphone \ ipad \ web \ pc \ mac \ wxapp
     * @apiHeader {string} XX-Token token信息，登录后返回
     * @apiHeader {string} XX-Api-Version api的版本信息
     * @apiName  checkStatus
     * @apiGroup  output
     * @apiVersion 0.0.1
     * @apiDescription 检查出库单状态
     *
     * @apiParam {string} bomId 出库单
     *
     * @apiSuccess {string} code 0 | 221   当code为221的时候，说明已经备料完成了
     * @apiSuccess {string} msg 备料中  | 备料完成
     * @apiError  Error
     **/
    public function checkStatus()
    {
        $bomId = input('bomId');
        $service = OutputFactory::getBomService($this->getType($bomId));
        $result = $service->checkBomStatus($bomId, $this->getStorageUuid(), $this->getNickname());
        switch ($result['status']) {
            case 0:
                $this->success('备料中');
                break;
            case 1:
                $this->success('备料完成', null, Constant::RETURN_CODE_OUTPUT_COMPLETE);
                break;
            default:
                $this->error('请求失败');
        }
    }

    /**
     * @api {GET} /api/storage/output/reels_check 3.检查物料
     * @apiHeader {string} XX-Device-Type 说明登录的设备 mobile \ android \ iphone \ ipad \ web \ pc \ mac \ wxapp
     * @apiHeader {string} XX-Token token信息，登录后返回
     * @apiHeader {string} XX-Api-Version api的版本信息
     * @apiName  checkReels
     * @apiGroup  output
     * @apiVersion 0.0.1
     * @apiDescription 检查扫描物料是否在出库中
     *
     * @apiParam {string} bomId 出库单
     * @apiParam {string} reelId reelId
     *
     * @apiSuccess {string} code 0 | 222   当code为222的时候，说明扫描的是错料
     * @apiSuccess {string} msg 备料中  | 备料完成
     * @apiSuccess {object} data 获取成功
     * @apiSuccess {int} data.planCount 应发数量
     * @apiSuccess {int} data.currentCount 当前数量
     * @apiSuccess {string} data.count reelId数量
     * @apiSuccess {string} data.materielId 物料号
     * @apiSuccess {#} data.  当code=0时，全部参数都有。当code=222时，只有以下两个参数
     * @apiSuccess {string} data.seatCode 站位号
     * @apiSuccess {string} data.containerCode 容器号
     * @apiError  Error
     **/
    public function checkReels()
    {
        $bomId = input('bomId');
        $reelId = input('reelId');
        $service = OutputFactory::getBomService($this->getType($bomId));
        $result = $service->checkReels($bomId, $reelId, $this->getStorageUuid());
        switch ($result['status']) {
            case -1:
                $this->error('该物料不在库中');
                break;
            case 1:
                $this->success('获取成功', $result['data']);
                break;
            case 2:
                $this->success('扫描的是错料', $result['data'], Constant::RETURN_CODE_OUTPUT_WRONG_MATERIEL);
                break;
            default:
                $this->error('请求失败');
        }
    }

    /**
     * @api {PUT} /api/storage/output/reels_output 4.物料出库
     * @apiHeader {string} XX-Device-Type 说明登录的设备 mobile \ android \ iphone \ ipad \ web \ pc \ mac \ wxapp
     * @apiHeader {string} XX-Token token信息，登录后返回
     * @apiHeader {string} XX-Api-Version api的版本信息
     * @apiName  outputReels
     * @apiGroup  output
     * @apiVersion 0.0.1
     * @apiDescription 将物料出具
     *
     * @apiParam {string} bomId bomId
     * @apiParam {string} reelId reelId
     * @apiParam {int} currentCount 出库数量
     * @apiParam {int} originalCount 原有数量
     *
     * @apiSuccess {string} code 0 | 221 | 223   221 出库流程走完了。 223 需要归还余料
     * @apiSuccess {string} msg
     * @apiSuccess {object} data
     * @apiSuccess {object} data.carData
     * @apiSuccess {string} data.carData.carId  需要装车的carId
     * @apiSuccess {string} data.carData.seatCode 需要装车的carId
     * @apiError  Error
     **/
    public function outputReels()
    {
        $bomId = input('bomId');
        $reelId = input('reelId');
        $currentCount = input('currentCount');
        $originalCount = input('originalCount');
        $service = OutputFactory::getBomService($this->getType($bomId));
        $storageUuid = $this->getStorageUuid();
        $result = $service->outputReels($bomId, $reelId, $currentCount, $originalCount, $storageUuid, $this->getNickname());
        switch ($result['status']) {
            case -3:
                $this->error('该物料不在库中');
                break;
            case -2:
                $this->error('该物料已出库');
                break;
            case -1:
                $this->error('该批次物料已经出够了');
                break;
            case 0:
                $this->error('出库失败');
                break;
            case 1:
                $this->success('出库成功', $result['data']);
                break;
            case 2:
                $this->success('出库成功', $result['data'], Constant::RETURN_CODE_OUTPUT_COMPLETE);
                break;
            case 3:
                $this->success('出库成功', $result['data'], Constant::RETURN_CODE_OUTPUT_LEFT_MATERIEL);
                break;
        }
    }

    /**
     * @api {PUT} /api/storage/output/materiel_revert 5.物料归还
     * @apiHeader {string} XX-Device-Type 说明登录的设备 mobile \ android \ iphone \ ipad \ web \ pc \ mac \ wxapp
     * @apiHeader {string} XX-Token token信息，登录后返回
     * @apiHeader {string} XX-Api-Version api的版本信息
     * @apiName  revertMateriel
     * @apiGroup  output
     * @apiVersion 0.0.1
     * @apiDescription 将物料出库
     *
     * @apiParam {string} bomId bomId
     * @apiParam {string} reelId reelId
     * @apiParam {string} seatCode seatCode
     * @apiParam {string} containerCode containerCode
     * @apiParam {int} type 0 错料归还  1 余料归还
     * @apiParam {int} count 归还数量，当type = 1 的时候需要传该参数
     *
     * @apiSuccess {string} code 0 | 221   221 出库流程走完了。
     * @apiSuccess {string} msg
     * @apiError  Error
     **/
    public function revertMateriel()
    {
        $bomId = input('bomId');
        $reelId = input('reelId');
        $seatCode = input('seatCode');
        $containerCode = input('containerCode');
        $count = input('count');
        $type = input('type');
        $service = OutputFactory::getBomService($this->getType($bomId));
        $result = [];
        if ($type == 0) {
            $result = $service->revertWrongMateriel($bomId, $reelId, $seatCode, $containerCode, $this->getStorageUuid());
        } elseif ($type == 1) {
            $result = $service->revertLeftMateriel($bomId, $reelId, $seatCode, $containerCode, $this->getStorageUuid(), $count, $this->getNickname());
        } else {
            $this->error('不存在这个类型');
        }
        switch ($result['status']) {
            case 0:
                $this->error('站位号不一致');
                break;
            case 1:
                $this->success('归还成功');
                break;
            case 2:
                $this->success('出库完成', [], Constant::RETURN_CODE_OUTPUT_COMPLETE);
                break;
        }

    }

    private function getType($bomId)
    {
        $bomInfo = BomService::getBomInfo($bomId);
        return $bomInfo->getData('type');
    }
}